vector类型的功能是通过vec类使用，vec类表示一组数据元素。vec类模板的构造函数、成员函数和非成员函数的接口描述在图11-1、11-4和11-5中。\par

图11-2中的XYZW成员只有在numElements <= 4时才可用。RGBA成员只有在numElements == 4时可用。\par

图11-3中的成员lo、hi、odd和even只有在numElements > 1的情况下才可用。\par

\hspace*{\fill} \par %插入空行
图11-1 vec类声明和成员函数
\begin{lstlisting}[caption={}]
vec Class declaration
template <typename dataT, int numElements> class vec; 
vec Class Members 
using element_type = dataT; 
vec(); 
explicit vec(const dataT &arg); 
template <typename … argTN> vec(const argTN&... args); 
vec(const vec<dataT, numElements> &rhs); 

#ifdef __SYCL_DEVICE_ONLY__ // available on device only
vec(vector_t openclVector); 
operator vector_t() const; 
#endif

operator dataT() const; // Available only if numElements == 1 
size_t get_count() const; 
size_t get_size() const;

template <typename convertT, rounding_mode roundingMode> 
vec<convertT, numElements> convert() const; 
template <typename asT> asT as() const;
\end{lstlisting}

\hspace*{\fill} \par %插入空行
图11-2 swizzled\_vec的成员函数
\begin{lstlisting}[caption={}]
template<int… swizzleindexes>
__swizzled_vec__ swizzle() const; 
__swizzled_vec__ XYZW_ACCESS() const; 
__swizzled_vec__ RGBA_ACCESS() const; 
__swizzled_vec__ INDEX_ACCESS() const; 

#ifdef SYCL_SIMPLE_SWIZZLES
// Available only when numElements <= 4 
// XYZW_SWIZZLE is all permutations with repetition of: 
// x, y, z, w, subject to numElements
__swizzled_vec__ XYZW_SWIZZLE() const;

// Available only when numElements == 4 
// RGBA_SWIZZLE is all permutations with repetition of: r, g, b, a. 
__swizzled_vec__ RGBA_SWIZZLE() const; 
#endif
\end{lstlisting}

\hspace*{\fill} \par %插入空行
图11-3 vec的函数操作符
\begin{lstlisting}[caption={}]
__swizzled_vec__ lo() const; 
__swizzled_vec__ hi() const; 
__swizzled_vec__ odd() const; 
__swizzled_vec__ even() const; 

template <access::address_space addressSpace> 
	void load(size_t offset, mult_ptr ptr<dataT, addressSpace> ptr); 
template <access::address_space addressSpace>
	void store(size_t offset, mult_ptr ptr<dataT, addressSpace> ptr) const;
	
vec<dataT, numElements> &operator=(const vec<dataT, numElements> &rhs);
vec<dataT, numElements> &operator=(const dataT &rhs); 
vec<RET, numElements> operator!(); 

// Not available for floating point types:
vec<dataT, numElements> operator~();
\end{lstlisting}


\hspace*{\fill} \par %插入空行
图11-4 vec的成员函数
\begin{table}[H]
	\begin{tabular}{|l|l|l|}
		\hline
		成员函数(OP)类型                                                                                                                                     & \begin{tabular}[c]{@{}l@{}}对于所有类型\\可能支持的操作 \end{tabular}                                                                 & \begin{tabular}[c]{@{}l@{}}对于整型可能\\支持的操作\end{tabular}                                                                         \\ \hline
		\begin{tabular}[c]{@{}l@{}}vec\textless{}dataT, numElements\textgreater\\ operatorOP(const vec\textless{}dataT, numElements\textgreater{}\&rhs) const;\end{tabular}  & \multirow{2}{*}{+,-,*,/}                                                                                                             & \multirow{2}{*}{\begin{tabular}[c]{@{}l@{}}\%,\&,|,\textasciicircum{},\\ \textless{}\textless{},\textgreater{}\textgreater{}\end{tabular}}          \\ \cline{1-1}
		\begin{tabular}[c]{@{}l@{}}vec\textless{}dataT, numElements\textgreater\\ operatorOP(const dataT \&rhs) const\end{tabular}                                           &                                                                                                                                      &                                                                                                                                                     \\ \hline
		\begin{tabular}[c]{@{}l@{}}vec\textless{}dataT, numElements\textgreater\\ \&operatorOP(const vec\textless{}dataT, numelements\textgreater \&rhs) const;\end{tabular} & \multirow{2}{*}{\begin{tabular}[c]{@{}l@{}}+=,-=,*=,\\ /=\end{tabular}}                                                              & \multirow{2}{*}{\begin{tabular}[c]{@{}l@{}}\%=,\&=,|=,\\ \textasciicircum{}=,\textless{}\textless{}=,\\ \textgreater{}\textgreater{}=\end{tabular}} \\ \cline{1-1}
		\begin{tabular}[c]{@{}l@{}}vec\textless{}dataT, numElements\textgreater\\ \&operatorOP(const dataT \&rhs) const;\end{tabular}                                        &                                                                                                                                      &                                                                                                                                                     \\ \hline
		\begin{tabular}[c]{@{}l@{}}vec\textless{}RET, numElements\textgreater\\ operatorOP(const vec\textless{}dataT,numElements\textgreater \&rhs) const;\end{tabular}      & \multirow{2}{*}{\begin{tabular}[c]{@{}l@{}}\&\&,||,==,\\ !=,\textless{},\textgreater{},\textless{}=,\\ \textgreater{}=\end{tabular}} & \multirow{2}{*}{}                                                                                                                                   \\ \cline{1-1}
		\begin{tabular}[c]{@{}l@{}}vec\textless{}RET, numElements\textgreater\\ operatorOP(const dataT \&rhs) const;\end{tabular}                                            &                                                                                                                                      &                                                                                                                                                     \\ \hline
		\begin{tabular}[c]{@{}l@{}}vec\textless{}dataT, numElements\textgreater\\ \&operatorOP() const;\end{tabular}                                                         & \multirow{2}{*}{++,--}                                                                                                               & \multirow{2}{*}{}                                                                                                                                   \\ \cline{1-1}
		\begin{tabular}[c]{@{}l@{}}vec\textless{}dataT, numElements\textgreater\\ operatorOP(int) const;\end{tabular}                                                        &                                                                                                                                      &                                                                                                                                                     \\ \hline
	\end{tabular}
\end{table}


\hspace*{\fill} \par %插入空行
图11-5 vec的非成员函数
\begin{table}[H]
	\begin{tabular}{|l|l|l|}
		\hline
		成员函数(OP)类型                                                                                                                                                                                                               & \begin{tabular}[c]{@{}l@{}}对于所有类型\\可能支持的操作\end{tabular}                                                & \begin{tabular}[c]{@{}l@{}}对于非浮点类型\\可能支持的操作\end{tabular} \\ \hline
		\begin{tabular}[c]{@{}l@{}}template\textless{}typename dataT, int numElements\textgreater\\ vec\textless{}dataT, numElements\textgreater\\ operatorOP(const dataT, \&lhs,\\ const vec\textless{}dataT, numElements\textgreater \& rhs);\end{tabular} & +,-,*,/                                                                                                             & \%,\&,|,\textasciicircum{},\textless{}\textless{}.\textgreater{}\textgreater{}      \\ \hline
		\begin{tabular}[c]{@{}l@{}}template\textless{}typename dataT, int numElements\textgreater\\ vec\textless{}RET, numElements\textgreater\\ operatorOP(const dataT \&lhs,\\ const vec\textless{}dataT, numElements\textgreater \&rhs);`\end{tabular}    & \begin{tabular}[c]{@{}l@{}}\&\&,||,==,\\ !=,\textless{},\textgreater{},\textless{}=,\\ \textgreater{}=\end{tabular} &                                                                                     \\ \hline
	\end{tabular}
\end{table}

\hspace*{\fill} \par %插入空行
\textbf{加载和存储成员函数}

向量的加载和存储操作，是用于加载和存储向量元素的vec类的成员。这些操作可以是指向或来自与向量通道类型相同的元素数组。如图11-6所示。\par

\hspace*{\fill} \par %插入空行
图11-6 使用加载和存储成员函数。
\begin{lstlisting}[caption={}]
buffer fpBuf(fpData);
queue Q;
Q.submit([&](handler& h){
	accessor buf{fpBuf, h};
	
	h.parallel_for(size, [=](id<1> idx){
		size_t offset = idx[0]/16;
		float16 inpf16;
		inpf16.load(offset, buf.get_pointer());
		float16 result = inpf16 * 2.0f;
		result.store(offset, buf.get_pointer());
	});
});
\end{lstlisting}

vec类中，dataT和numElements是反映vec的组件类型和维数的模板参数。\par

load()成员函数模板从multi\_ptr地址的内存中读取dataT类型的值，dataT元素的offset乘以numElements*offset，并将这些值写入vec的通道中。\par

store()成员函数模板将读取向量的通道，并将这些值写入multi\_ptr地址的内存中，dataT元素中的offset乘以numElements*offset。\par

形参是multi\_ptr，而不是访问器，可以使用本地创建的指针，以及主机指针。\par

multi\_ptr的数据类型是dataT，即vec类专门化组件的数据类型。这要求传递给load()或store()的指针必须与vec实例本身的类型匹配。\par

\hspace*{\fill} \par %插入空行
\textbf{混合(Swizzle)操作}

图形应用程序中，混合意味着重新安排矢量的数据元素。例如，如果a = \{1,2,3,4，\}，并且知道一个四元向量的分量可以称为\{x, y, z, w\}，可以写成b = a.wxyz()，变量b的结果是\{4,1,2,3 \}。这种形式的代码在GPU程序中很常见，GPU应用程序中有高效的硬件进行此类操作。混合可以通过两种方式进行:\par

\begin{itemize}
	\item 通过调用vec的swizzle成员函数，该函数接受从0到numElements-1之间的可变数目的整型模板参数，指定swizzle索引
	\item 通过调用简单的swizzle成员函数，如XYZW\_SWIZZLE和RGBA\_SWIZZLE
\end{itemize}

简单的swizzles函数只对最多4个元素的向量可用，并且只有在包含SYCL.hpp之前定义了宏SYCL\_SIMPLE\_SWIZZLES时才可用。这两种情况下，返回类型是一个\_\_swizzled\_vec\_\_实例，实现定义的临时类表示原始vec实例的swizzle。swizle成员函数模板和简单的swizle成员函数都允许重复swizle索引。图11-7展示了\_\_swizled \_vec\_\_的简单用法。\par

\hspace*{\fill} \par %插入空行
图11-7 使用\_\_swizled \_vec\_\_类的示例
\begin{lstlisting}[caption={}]
constexpr int size = 16;

std::array<float4, size> input;
for (int i = 0; i < size; i++)
	input[i] = float4(8.0f, 6.0f, 2.0f, i);

buffer B(input);

queue Q;
Q.submit([&](handler& h) {
	accessor A{B, h};
	
	// We can access the individual elements of a vector by using 
	// the functions x(), y(), z(), w() and so on.
	//
	// "Swizzles" can be used by calling a vector member equivalent
	// to the swizzle order that we need, for example zyx() or any
	// combination of the elements. The swizzle need not be the same
	// size as the original vector.
	h.parallel_for(size, [=](id<1> idx) {
		auto b = A[idx];
		float w = b.w();
		float4 sw = b.xyzw();
		sw = b.xyzw() * sw.wzyx();;
		sw = sw + w;
		A[idx] = sw.xyzw();
	});
});
\end{lstlisting}
































